package com.chatsystem.service;

import com.chatsystem.entity.Message;
import com.chatsystem.entity.User;
import com.chatsystem.repository.MessageRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

/**
 * 消息服务类
 * 
 * @author ChatSystem
 * @version 1.0.0
 */
@Service
@RequiredArgsConstructor
@Transactional
public class MessageService {

    private final MessageRepository messageRepository;
    private final UserService userService;

    /**
     * 发送消息
     * 
     * @param senderId 发送者ID
     * @param receiverId 接收者ID
     * @param content 消息内容
     * @param messageType 消息类型
     * @param fileUrl 文件URL（可选）
     * @param fileName 文件名（可选）
     * @param fileSize 文件大小（可选）
     * @return 消息对象
     */
    public Message sendMessage(Long senderId, Long receiverId, String content, 
                             Message.MessageType messageType, String fileUrl, 
                             String fileName, Long fileSize) {
        
        // 查找发送者和接收者
        Optional<User> senderOpt = userService.findById(senderId);
        Optional<User> receiverOpt = userService.findById(receiverId);
        
        if (senderOpt.isEmpty() || receiverOpt.isEmpty()) {
            throw new RuntimeException("用户不存在");
        }

        User sender = senderOpt.get();
        User receiver = receiverOpt.get();

        // 创建消息
        Message message = new Message();
        message.setContent(content);
        message.setSender(sender);
        message.setReceiver(receiver);
        message.setMessageType(messageType);
        message.setFileUrl(fileUrl);
        message.setFileName(fileName);
        message.setFileSize(fileSize);
        message.setIsRead(false);
        message.setIsRecalled(false);

        return messageRepository.save(message);
    }

    /**
     * 获取两个用户之间的消息记录
     * 
     * @param user1Id 用户1 ID
     * @param user2Id 用户2 ID
     * @param page 页码
     * @param size 每页大小
     * @return 消息分页
     */
    public Page<Message> getMessagesBetweenUsers(Long user1Id, Long user2Id, int page, int size) {
        Optional<User> user1Opt = userService.findById(user1Id);
        Optional<User> user2Opt = userService.findById(user2Id);
        
        if (user1Opt.isEmpty() || user2Opt.isEmpty()) {
            throw new RuntimeException("用户不存在");
        }

        User user1 = user1Opt.get();
        User user2 = user2Opt.get();

        Pageable pageable = PageRequest.of(page, size, Sort.by("createdAt").descending());
        return messageRepository.findMessagesBetweenUsers(user1, user2, pageable);
    }

    /**
     * 获取用户未读消息
     * 
     * @param userId 用户ID
     * @return 未读消息列表
     */
    public List<Message> getUnreadMessages(Long userId) {
        Optional<User> userOpt = userService.findById(userId);
        if (userOpt.isEmpty()) {
            throw new RuntimeException("用户不存在");
        }

        return messageRepository.findByReceiverAndIsReadFalseOrderByCreatedAtDesc(userOpt.get());
    }

    /**
     * 标记消息为已读
     * 
     * @param messageId 消息ID
     * @return 更新后的消息
     */
    public Message markAsRead(Long messageId) {
        Optional<Message> messageOpt = messageRepository.findById(messageId);
        if (messageOpt.isEmpty()) {
            throw new RuntimeException("消息不存在");
        }

        Message message = messageOpt.get();
        message.setIsRead(true);
        return messageRepository.save(message);
    }

    /**
     * 撤回消息（1分钟内）
     * 
     * @param messageId 消息ID
     * @param userId 用户ID
     * @return 是否撤回成功
     */
    public boolean recallMessage(Long messageId, Long userId) {
        Optional<Message> messageOpt = messageRepository.findById(messageId);
        if (messageOpt.isEmpty()) {
            throw new RuntimeException("消息不存在");
        }

        Message message = messageOpt.get();

        // 检查是否是消息发送者
        if (!message.getSender().getId().equals(userId)) {
            throw new RuntimeException("只能撤回自己发送的消息");
        }

        // 检查消息是否已被撤回
        if (message.getIsRecalled()) {
            throw new RuntimeException("消息已被撤回");
        }

        // 检查是否在1分钟内
        LocalDateTime timeLimit = LocalDateTime.now().minusMinutes(1);
        if (message.getCreatedAt().isBefore(timeLimit)) {
            throw new RuntimeException("消息发送超过1分钟，无法撤回");
        }

        // 撤回消息
        message.setIsRecalled(true);
        message.setRecalledAt(LocalDateTime.now());
        messageRepository.save(message);

        return true;
    }

    /**
     * 获取可撤回的消息列表
     * 
     * @param userId 用户ID
     * @return 可撤回的消息列表
     */
    public List<Message> getRecallableMessages(Long userId) {
        Optional<User> userOpt = userService.findById(userId);
        if (userOpt.isEmpty()) {
            throw new RuntimeException("用户不存在");
        }

        LocalDateTime timeLimit = LocalDateTime.now().minusMinutes(1);
        return messageRepository.findRecallableMessages(userOpt.get(), timeLimit);
    }

    /**
     * 根据ID查找消息
     * 
     * @param messageId 消息ID
     * @return 消息对象
     */
    public Optional<Message> findById(Long messageId) {
        return messageRepository.findById(messageId);
    }

    /**
     * 统计用户未读消息数量
     * 
     * @param userId 用户ID
     * @return 未读消息数量
     */
    public long countUnreadMessages(Long userId) {
        Optional<User> userOpt = userService.findById(userId);
        if (userOpt.isEmpty()) {
            return 0;
        }

        return messageRepository.countByReceiverAndIsReadFalse(userOpt.get());
    }
} 